package towerDefense;

import java.util.ArrayList;

/**
 * Contains all the objects (towers, enemies, projectiles) in the game world. Keeps track of each
 * round and time before next wave. 
 * 
 * @author Guillermo Mendez-Kestler
 *
 */
public class World {
	/**
	 * The HEIGHT of the MAP
	 */
	public final static int MAP_HEIGHT = 1000;

	/**
	 * The WIDTH of the MAP
	 */
	public final static int MAP_WIDTH = 1000;

	/**
	 * ArrayList of all towers in the world
	 */
	private static ArrayList<T_Tower> worldTowers = new ArrayList<T_Tower>();

	/**
	 * ArrayList of all projectiles in the world
	 */
	private static ArrayList<T_Projectile> worldProjectiles = new ArrayList<T_Projectile>();

	/**
	 * ArrayList of all enemies in the world
	 */
	private static ArrayList<T_Enemy> worldEnemies = new ArrayList<T_Enemy>();

	/**
	 * Ordered ArrayList of all objects in the world
	 * @deprecated 
	 */
	private static ArrayList<T_Object> worldObjects = new ArrayList<T_Object>();

	/**
	 * Returns an array with all objects in the world. The array is organized in order of 
	 * importance. The order is Towers, Enemies, Projectiles.  
	 * 
	 * @return An array with all objects in the world. The array is organized in order of 
	 * importance. The order is Towers, Enemies, Projectiles.  
	 */
	public static T_Object[] getObjects(){
		ArrayList<T_Object> orderedWorldObjs = new ArrayList<T_Object>();
		for (T_Tower obj : getTowers()){
			orderedWorldObjs.add((T_Object) obj);
		}
		for (T_Enemy obj : getEnemies()){
			orderedWorldObjs.add((T_Object) obj);
		}
		for (T_Projectile obj : getProjectiles()){
			orderedWorldObjs.add((T_Object) obj);
		}
		return orderedWorldObjs.toArray(new T_Object[orderedWorldObjs.size()]);
	}

	/**
	 * Returns an array with all the towers in the world. 
	 * 
	 * @return An array with all the towers in the world. 
	 */
	public static T_Tower[] getTowers(){
		return worldTowers.toArray(new T_Tower[worldTowers.size()]);
	}

	/**
	 * Returns an array with all the enemies in the world. 
	 * 
	 * @return An array with all the enemies in the world. 
	 */
	public static T_Enemy[] getEnemies(){
		return worldEnemies.toArray(new T_Enemy[worldEnemies.size()]);
	}

	/**
	 * Returns an array with all the projectiles in the world. 
	 * 
	 * @return An array with all the projectiles in the world. 
	 */
	public static T_Projectile[] getProjectiles(){
		return worldProjectiles.toArray(new T_Projectile[worldProjectiles.size()]);
	}

	/**
	 * Adds an object to the world list. 
	 * 
	 * @param obj Object to be added to the world.
	 */
	public static void addObject(T_Object obj, int TYPE){
		
	}

	/**
	 * Adds an tower to the world list. 
	 * 
	 * @param tower Tower to be added to the world.
	 */
	public static void addT_Tower(T_Tower tower){
		worldTowers.add(tower);
	}

	/**
	 * Adds an projectile to the world list. 
	 * 
	 * @param projectile projectile to be added to the world.
	 */
	public static void addT_Projectile(T_Projectile projectile){
		worldProjectiles.add(projectile);
	}

	/**
	 * Adds an enemy to the world list. 
	 * 
	 * @param enemy enemy to be added to the world.
	 */
	public static void addT_Enemy(T_Enemy enemy){
		worldEnemies.add(enemy);
	}

	/**
	 * <strike>Changes the object with updated information.</strike> 
	 * The {@link #worldObjects} is a container for all objects (the 
	 * different types) and doesn't need to move anything in the field. 
	 * The Object itself will contain it's proper coordinates.   
	 * 
	 * @deprecated
	 * @param obj The object to be moved. 
	 * @return {@code True} if the Object was moved with the updated 
	 * information. 
	 */
	public static boolean moveT_Object(T_Object obj){
		if (worldObjects.contains(obj)){ 
			worldObjects.set(worldObjects.indexOf(obj), obj);
			return true;
		} else 
			return false;
	}

	/**
	 * If the enemy died the enemy is removed from the game world. 
	 * 
	 * @param enemy The enemy to remove from the game world. 
	 * @return {@code True} if the enemy was removed from the game
	 * world. 
	 */
	public static boolean removeEnemy(T_Enemy enemy) {
		return worldEnemies.remove(enemy);
	}

}